﻿using Cheems.Interface.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cheems.Service.Configuration
{
    /// <summary>
    /// 配置服务：提供了灵活的配置管理、实时监控、自动恢复功能
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ConfigService<T> : IConfig<T> where T : new()
    {
        private readonly string _configFilePath;
        private T _config;
        private T _lastValidConfig; // 保存上一次有效的配置
        private FileSystemWatcher _fileWatcher;

        public event Action<T> OnConfigChanged;

        /// <summary>
        /// 默认构造函数，使用默认路径和默认值
        /// </summary>
        public ConfigService()
        {
            // 使用默认路径 Config/xx.json，其中 xx 是泛型类型的名称
            var configFolder = Path.Combine(Directory.GetCurrentDirectory(), "Config");
            if (!Directory.Exists(configFolder))
            {
                Directory.CreateDirectory(configFolder); // 自动创建文件夹
            }

            _configFilePath = Path.Combine(configFolder, $"{typeof(T).Name}.json");

            InitializeWatcher();
            LoadConfig();
        }

        /// <summary>
        /// 传入配置路径的构造函数
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        public ConfigService(string configFilePath)
        {
            _configFilePath = configFilePath;

            InitializeWatcher();
            LoadConfig();
        }

        /// <summary>
        /// 传入默认值的构造函数
        /// </summary>
        /// <param name="defaultConfig">默认配置值</param>
        public ConfigService(T defaultConfig)
        {
            // 使用默认值，优先使用本地文件配置
            var configFolder = Path.Combine(Directory.GetCurrentDirectory(), "Config");
            if (!Directory.Exists(configFolder))
            {
                Directory.CreateDirectory(configFolder); // 自动创建文件夹
            }

            _configFilePath = Path.Combine(configFolder, $"{typeof(T).Name}.json");

            _lastValidConfig = defaultConfig;
            _config = defaultConfig; // 如果文件不存在或损坏，将使用默认值

            InitializeWatcher();
            LoadConfig();
        }

        /// <summary>
        /// 传入配置路径和默认值的构造函数
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        /// <param name="defaultConfig">默认配置值</param>
        public ConfigService(string configFilePath, T defaultConfig)
        {
            _configFilePath = configFilePath;

            _lastValidConfig = defaultConfig;
            _config = defaultConfig; // 如果文件不存在或损坏，将使用默认值

            InitializeWatcher();
            LoadConfig();
        }

        /// <summary>
        /// 初始化文件变化监听器
        /// </summary>
        private void InitializeWatcher()
        {
            _fileWatcher = new FileSystemWatcher(Path.GetDirectoryName(_configFilePath))
            {
                Filter = Path.GetFileName(_configFilePath),
                NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size,
                EnableRaisingEvents = true
            };

            // 增加事件监听
            _fileWatcher.Changed += (sender, args) =>
            {
                // 防止事件被触发过多次，加入延时或其他防抖处理
                Task.Delay(500).ContinueWith(t =>
                {
                    LoadConfig();
                    OnConfigChanged?.Invoke(GetConfig());
                });
            };
        }


        /// <summary>
        /// 加载配置文件
        /// </summary>
        private void LoadConfig()
        {
            if (File.Exists(_configFilePath))
            {
                try
                {
                    // 使用 FileShare.ReadWrite 允许文件被其他进程读取或写入
                    var json = File.ReadAllText(_configFilePath, Encoding.UTF8);
                    _config = JsonConvert.DeserializeObject<T>(json);
                    _lastValidConfig = _config; // 更新为最新有效配置
                }
                catch (IOException ex)
                {
                    // 可能是文件正在被其他进程占用，稍后重试
                    Task.Delay(500).Wait();  // 延时后再试一次，避免过于频繁地重试
                    LoadConfig();  // 重新加载配置
                }
                catch (JsonException)
                {
                    _config = _lastValidConfig ?? new T(); // 如果没有有效配置，则生成新的
                    SaveConfig(); // 保存修复后的配置
                }
            }
            else
            {
                _config = _lastValidConfig ?? new T(); // 文件不存在时创建新的配置或使用最后有效配置
                _lastValidConfig = _config; // 保存此配置为有效配置
                SaveConfig(); // 保存新创建的配置
            }
        }


        /// <summary>
        /// 保存配置到文件
        /// </summary>
        private void SaveConfig()
        {
            var json = JsonConvert.SerializeObject(_config, Formatting.Indented);
            File.WriteAllText(_configFilePath, json, Encoding.UTF8);
        }

        /// <summary>
        /// 获取当前配置
        /// </summary>
        /// <returns></returns>
        public T GetConfig()
        {
            return _config;
        }

        /// <summary>
        /// 完整更新配置
        /// </summary>
        /// <param name="updateData"></param>
        public void UpdateConfig(T updateData)
        {
            _config = updateData;
            SaveConfig();
        }

        /// <summary>
        /// 修改配置
        /// </summary>
        /// <param name="updateAction"></param>
        public void UpdateConfig(Action<T> updateAction)
        {
            updateAction(_config);
            SaveConfig(); // 修改后立即保存
        }



        /// <summary>
        /// 停止监听
        /// </summary>
        public void StopWatching()
        {
            _fileWatcher.EnableRaisingEvents = false;
            _fileWatcher.Dispose();
        }
    }
}
